package net.uiiang.android.alkaid.core;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

import net.uiiang.android.alkaid.Constant;
import net.uiiang.android.alkaid.R;
import net.uiiang.android.alkaid.helper.EfficientAdapter;
import net.uiiang.android.alkaid.helper.FileManagerDbAdapter;
import net.uiiang.android.alkaid.object.FileItem;
import net.uiiang.android.alkaid.utils.FileUtils;

import org.apache.commons.io.FilenameUtils;

import android.app.ListActivity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;

public class ListFile extends ListActivity {

    /**
     * 当前目录中的文件list,在fill方法中填充此list
     */
    protected ArrayList<FileItem> directoryEntries = new ArrayList<FileItem>();

    /**
     * 当前浏览的目录
     */
    protected File currentDirectory = new File("/");

    /**
     * 设置显示哪些类型的文件
     */
    protected String[] externalAllowExtensions = {};

    /**
     * 设置根目录
     */
    protected File externalRootDirectory = new File("/");

    /**
     * 设置排除显示的文件夹
     */
    protected ArrayList<File> externalExcludeDirectory = new ArrayList<File>();

    /**
     * 目录显示方式 SHOW_TYPE_ALL = 0 为显示全部文件和文件夹 SHOW_TYPE_ONLY_FILE = 1 为只显示文件
     * SHOW_TYPE_ONLY_DIRECTORY = 2 为只显示文件夹
     */
    protected int externalShowType = 0;

    /**
     * 设置使用哪些菜单
     */
    protected int[] externalUseMenuItems = {};

    /**
     * 设置是否使用简单文件预览
     */
    protected boolean externalUseSimpleView = true;

    /**
     * 设置是否显示文件信息
     */
    protected boolean externalShowInfoInList = false;

    /**
     * 设置是否显示文件后缀名
     */
    protected boolean externalShowFileExtension = true;

    /**
     * 设置是否使用动画效果
     */
    protected boolean externalAnimationList = true;

    /**
     * 设置是否可以多选
     */
    protected boolean externalMutipleSelect = false;

    /**
     * 当前控制文件,临时文件
     */
    protected File controlFile = null;

    /**
     * 是否为第三方调用
     */
    protected boolean thridPartyCall = true;

    /**
     * 是否使用全部菜单
     */
    protected boolean insideAllMenuAvailable = true;

    /**
     * 设置是否显示文件信息,保存Preferences中的设置
     */
    protected static boolean insideShowInfoInList = false;

    /**
     * 设置是否显示文件后缀名,保存Preferences中的设置
     */
    protected static boolean insideShowFileExtension = true;

    /**
     * 设置是否使用动画效果,保存Preferences中的设置
     */
    protected static boolean insideAnimationList = true;

    /**
     * 当第三方程序调用时,保存选择了哪些文件路径
     */
    protected String[] selectedFileArray = {};

    /**
     * 打开文件的路径,通过收藏夹打开文件时临时保存用
     */
    protected static String tmpOpenPathStr = null;

    // private ArrayList<String> favoritePathList = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(android.R.style.Theme_Black);
        // 更新设置信息
        updatePreferences();
        // 调用浏览文件根目录
        // favoritePathList = FileManagerDbAdapter.favoritePathList;
        browseToRoot();
        this.setSelection(0);
        // ListView listView = getListView();
        // listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        registerForContextMenu(getListView());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 从Preferences设置中返回时, 更新Preferences到变量
        // 并刷新当前浏览的目录,使Preferences修改生效
        updatePreferences();
        browseTo(this.currentDirectory);
    }

    @Override
    public void onResume() {
        super.onResume();
        // 在收藏夹中点击文件后,进入到这里,根据tmpOpenPathStr打开文件
        // 如果tmpOpenPathStr不为空并且存在

        if (tmpOpenPathStr != null && tmpOpenPathStr.trim().length() > 0) {
            // updatePreferences();
            File tmpFile = new File(tmpOpenPathStr);
            if (tmpFile.exists()) {
                // 当文件为目录时浏览到此目录
                if (tmpFile.isDirectory()) {
                    browseTo(tmpFile);
                } else {
                    // 当为文件时,浏览到此文件所在的目录并打开文件
                    browseTo(tmpFile.getParentFile());
                    openFile(tmpFile);
                }
            } else {
                // 若文件不存在则提示
                Toast.makeText(
                        this,
                        tmpOpenPathStr + " "
                                + getResources().getString(R.string.not_exist),
                        Toast.LENGTH_SHORT).show();
                browseToRoot();
            }
        } else {
            browseTo(currentDirectory);
        }
        tmpOpenPathStr = null;
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        // 得到当前点击的title
        String selectedFileString = this.directoryEntries.get(position)
                .getTitle();
        // 如果当前title为 .. 则返回上一级目录
        if (selectedFileString.equals(getString(R.string.up_one_level))) {
            this.upOneLevel();
        } else {
            File clickedFile = new File(this.currentDirectory.getAbsolutePath()
                    + "/" + selectedFileString
                    + this.directoryEntries.get(position).getFileExtension());
            if (clickedFile != null) {
                // System.out.println("onListItemClick call broto");
                this.browseTo(clickedFile);
            }
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle state) {
        // 横竖屏切换时得到之前浏览的文件夹并恢复该文件夹的浏览
        super.onRestoreInstanceState(state);
        String current_directory = state.getString("current_directory");
        // System.out.println("onRestoreInstanceState call broto");
        browseTo(new File(current_directory));
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // 横竖屏切换时保存当前浏览的文件夹
        outState.putString("current_directory", this.currentDirectory
                .getAbsolutePath());
    }

    /**
     * 删除文件操作
     */
    protected void deleteFile() {
        // System.out.println("deleteFile call broto");
        if (controlFile != null) {
            if (FileUtils.isFile(controlFile)) {
                // 如果是文件,直接删除并刷新目录
                controlFile.delete();
                browseTo(currentDirectory);
            } else if (FileUtils.isDirectory(controlFile)) {
                // 如果是文件夹,调用org.apache.commons.io.FileUtils删除,并刷新目录
                try {
                    org.apache.commons.io.FileUtils
                            .deleteDirectory(controlFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                browseTo(currentDirectory);
            }
        }
        controlFile = null;
    }

    protected void upOneLevel() {
        // System.out.println("upOneLevel call broto");
        if (this.currentDirectory.getParent() != null) {
            String directoryName = this.currentDirectory.getName();
            this.browseTo(this.currentDirectory.getParentFile());
            // 回退到上层文件夹时, 根据当前所在文件夹名计算位置并让屏幕滚动到这里
            for (int i = 0; i < directoryEntries.size(); i++) {

                FileItem fileItem = directoryEntries.get(i);
                if (fileItem.getTitle().equalsIgnoreCase(directoryName)) {
                    this.getListView().setSelection(i - 1 < 1 ? i : i - 1);
                    break;
                }
            }
        }
    }

    protected void browseToRoot() {
        this.setEnv();
        // 如果是外部调用并设定了根目录则以此为根目录浏览
        // System.out.println("browseToRoot call broto");
        if (FileUtils.isDirectory(this.externalRootDirectory)) {
            browseTo(this.externalRootDirectory);
        } else {
            // 否则默认"/"为根目录
            browseTo(new File("/"));
        }
    }

    public void browseTo(final File aDirectory) {
        // System.out.println("in browse to " + aDirectory.getAbsolutePath());
        if (aDirectory.isDirectory()) {
            this.setTitle(aDirectory.getAbsolutePath() + "  "
                    + getString(R.string.app_name));
            if (this.getParent() != null) {
                this.getParent().setTitle(
                        aDirectory.getAbsolutePath() + "  "
                                + getString(R.string.app_name));
            }
            this.currentDirectory = aDirectory;
            // updatePreferences();
            fill(aDirectory.listFiles());
            if ((!thridPartyCall && insideAnimationList)
                    || (thridPartyCall && externalAnimationList)) {
                setAnimation();
            }
        } else {
            openFile(aDirectory);
        }
    }

    protected void fill(File[] files) {
        this.directoryEntries.clear();
        // 如果当前目录的父目录不为空,并且为外部调用设置了根目录,当前目录不等于根目录,则添加 返回上层目录的标识
        if (this.currentDirectory.getParent() != null) {
            if (FileUtils.isDirectory(this.externalRootDirectory)
                    && !this.externalRootDirectory.getAbsolutePath().equals(
                            currentDirectory.getAbsolutePath())) {
                this.directoryEntries.add(new FileItem(
                        getString(R.string.up_one_level), "", getResources()
                                .getDrawable(R.drawable.uponelevel), "", "",
                        false));
            }
        }
        Drawable currentIcon = null;
        if (files != null && files.length > 0) {
            for (File currentFile : files) {
                // System.out.println(currentFile.getName() + "is hidden = "
                // + currentFile.isHidden());
                // 如果是外部设置的排除文件夹,则跳过此循环
                if (externalExcludeDirectory != null
                        && this.externalExcludeDirectory.contains(currentFile)) {
                    continue;
                }

                // 用来计数子文件夹数,在列表中显示文件详情时使用
                int directoryNum = 0;
                // 用来计数文件数,在列表中显示文件详情时使用
                int fileNum = 0;
                // 拼接文件详情的字符串
                String desc = "";
                // 当前文件的文件名
                String fileName = currentFile.getName();
                String fileType = "";
                String fileExtension = "";
                boolean fileFavorite = false;
                if (!thridPartyCall) {
                    fileFavorite = FileManagerDbAdapter.favoritePathList
                            .contains((String) currentFile.getAbsolutePath());
                }
                if (currentFile.isDirectory()) {
                    // 如果为外部调用并设置了只显示文件,则奶出当前循环
                    if (this.externalShowType == Constant.SHOW_TYPE_ONLY_FILE) {
                        continue;
                    }

                    fileType = Constant.FILE_TYPE_DIRECTORY;
                    currentIcon = getResources().getDrawable(R.drawable.folder);
                    // 如果设置为在列表中显示文件详情
                    if ((!thridPartyCall && insideShowInfoInList)
                            || (thridPartyCall && externalShowInfoInList)) {
                        File[] listFile = currentFile.listFiles();
                        if (listFile != null && listFile.length > 0) {
                            for (File file : listFile) {
                                if (file.isDirectory()) {
                                    directoryNum++;
                                } else {
                                    fileNum++;
                                }
                            }
                        }
                        desc = fileNum + getString(R.string.ge)
                                + getString(R.string.file) + "  "
                                + directoryNum + getString(R.string.ge)
                                + getString(R.string.directory);
                    }
                } else {
                    // 如果为外部调用并设置只显示文件夹,退出当前循环
                    if (this.externalShowType == Constant.SHOW_TYPE_ONLY_DIRECTORY) {
                        continue;
                    }

                    fileType = Constant.FILE_TYPE_FILE;
                    // String fileName = currentFile.getName();
                    if (this.externalAllowExtensions != null
                            && this.externalAllowExtensions.length > 0
                            && !FileUtils.checkAllowExtension(fileName,
                                    this.externalAllowExtensions)) {
                        continue;
                    }

                    currentIcon = FileUtils.getFileIconWithExtensions(this,
                            fileName);

                    // 如果设置为在列表中显示文件详情
                    if ((!thridPartyCall && insideShowInfoInList)
                            || (thridPartyCall && externalShowInfoInList)) {
                        FileUtils fileUtils = new FileUtils();
                        fileUtils.getFileInfo(currentFile);

                        desc = getString(R.string.view_info_size)
                                + fileUtils.getFileSizeString();
                    }
                    // 如果设置为不显示文件后缀名
                    if ((!thridPartyCall && !insideShowFileExtension)
                            || (thridPartyCall && !externalShowFileExtension)) {
                        fileExtension = "."
                                + FilenameUtils.getExtension(fileName);
                        fileName = FilenameUtils.removeExtension(fileName);
                    }

                }

                this.directoryEntries.add(new FileItem(fileName, desc,
                        currentIcon, fileType, fileExtension, fileFavorite));
            }
        }
        Collections.sort(this.directoryEntries);

        EfficientAdapter efficientAdapter = new EfficientAdapter(this,
                android.R.layout.simple_list_item_multiple_choice,
                externalMutipleSelect);
        this.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        efficientAdapter.setListItems(this.directoryEntries);
        this.setListAdapter(efficientAdapter);
    }

    public void setEnv() {
        Bundle extras = getIntent().getExtras();
        externalShowType = extras != null ? extras.getInt(
                Constant.DIRECTORY_SHOW_TYPE, 0) : 0;
        externalAllowExtensions = extras != null ? extras
                .getStringArray(Constant.ALLOW_EXTENSIONS) : new String[] {};
        externalRootDirectory = FileUtils
                .convertStringToFile(extras != null ? extras
                        .getString(Constant.ROOT_DIRECTORY) : "/");
        externalExcludeDirectory = FileUtils
                .convertFileArrayToFileList(extras != null ? extras
                        .getStringArray(Constant.EXCLUDE_DIRECTORY) : null);
        externalUseMenuItems = extras != null ? extras
                .getIntArray(Constant.USE_MENU_ITEMS) : null;
        if (externalUseMenuItems != null && externalUseMenuItems.length > 0) {
            insideAllMenuAvailable = false;
        }

        externalUseSimpleView = extras != null ? extras.getBoolean(
                Constant.USE_SIMPLE_VIEW, true) : true;

        externalShowInfoInList = extras != null ? extras.getBoolean(
                Constant.SHOW_INFO_IN_LIST, true) : true;

        externalShowFileExtension = extras != null ? extras.getBoolean(
                Constant.SHOW_FILE_EXTENSION, true) : true;

        externalAnimationList = extras != null ? extras.getBoolean(
                Constant.ANIMATION_LIST, true) : true;

        externalMutipleSelect = extras != null ? extras.getBoolean(
                Constant.MUTIPLE_SELECT_AVAILABLE, false) : false;

        thridPartyCall = extras != null ? extras.getBoolean(
                Constant.THIRD_PARTY_CALL, true) : true;

        tmpOpenPathStr = extras != null ? extras
                .getString(Constant.OPEN_PATH_STR) : null;

        // System.out.println("extral == " + extras == null);
        //                
        // System.out.println("thridPartyCall 2= " + thridPartyCall);
        // System.out.println("externalAnimationList 2= " + extras
        // .getBoolean(Constant.ANIMATION_LIST));
        // System.out.println("externalShowInfoInList 2= " + extras
        // .getBoolean(Constant.SHOW_INFO_IN_LIST));
        // System.out.println("externalShowFileExtension 2= " + extras
        // .getBoolean(Constant.SHOW_FILE_EXTENSION));
        // System.out.println("externalUseSimpleView 2= " + extras
        // .getBoolean(Constant.USE_SIMPLE_VIEW));
    }

    protected void openFile(final File aDirectory) {
    }

    protected void setAnimation() {
    }

    protected void updatePreferences() {
    }

}
